package com.tengju.support.application.message;

import com.tengju.support.application.shared.ApplicationException;
import com.tengju.support.application.shared.ApplicationExceptionCode;
import com.tengju.support.domain.model.message.Message;
import com.tengju.support.domain.model.message.MessageRepository;
import com.tengju.support.domain.model.message.MessageTask;
import com.tengju.support.domain.model.message.SendStatus;
import com.tengju.support.domain.service.NotificationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
@Service("smsSendStrategy")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class SmsSendStrategy implements MessageSendStrategy{

    private final NotificationService notificationService;
    private final MessageRepository messageBatchRelationRepository;

    private static final ExecutorService threadPool = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() * 2 -1,
            Runtime.getRuntime().availableProcessors() * 2 -1,
            60L, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(20480),
            Executors.defaultThreadFactory(),
            (r, executor) -> log.error("线程池队列已满")
    );


    @Override
    public boolean send(MessageTask messageTask, List<Message> messages) {

        boolean result = true;

        if (StringUtils.isEmpty(messageTask.getContent())) {
            throw ApplicationException.error(ApplicationExceptionCode.INVALID_DATA,"短信模版id为空");
        }

        Integer templateId = Integer.parseInt(messageTask.getContent());

        //发送短信
        List<Future<Boolean>> futures = new ArrayList<>();
        for (Message message : messages) {
            Future<Boolean> future = threadPool.submit(() -> sendSms(messageTask, templateId, message));
            futures.add(future);
        }

        //阻塞 等待所有线程执行完成
        for (Future<Boolean> future : futures) {
            try {
                future.get();
            } catch (Exception e) {
                log.error("短信发送失败,taskId:{}",messageTask.getTaskId().getValue());
                result = false;
            }
        }

        return result;

    }

    private Boolean sendSms(MessageTask messageTask, Integer templateId, Message message) {

        if (message.getExtra() == null ||
                StringUtils.isEmpty(message.getExtra().getAreaCode()) ||
                StringUtils.isEmpty(message.getExtra().getMobile())) {
            log.error("短信发送失败，手机号不存在");
            return false;
        }

        boolean result = notificationService.sms(message.getExtra().getAreaCode(),
                message.getExtra().getMobile(), templateId, messageTask.getTaskId());

        if (result) {
            //变更发送状态
            messageBatchRelationRepository.updateSendStatusByUserIdMessageId(
                    message.getUserId(), messageTask.getTaskId(), SendStatus.SEND);
            return true;
        }
        return false;
    }




}
